home *** CD-ROM | disk | FTP | other *** search
- /*
- * AuditDCMD.c
- * Copyright © 1992-93 Apple Computer Inc. All Rights Reserved.
- * Programmed by Martin Minow,
- * Internet: minow@apple.com
- * AppleLink: MINOW
- * Version of January 4, 1993
- *
- * Provide formatted access to a Audit from within MacsBug.
- *
- * The following commands are supported:
- *
- * Audit NAME on Turn logging on for this log
- * Audit NAME off Turn logging off
- * Audit NAME write Display the entire log (including
- * free areas that contain "real" data).
- * Note that the log area must already have been created.
- *
- * AuditDCMD is built by the following commands (they are best
- * placed in a suitable Makefile). BuildDCMD and the libraries
- * are distributed with MacsBug. This sequence assumes MPW 3.2
- * + cut here
- C ∂
- -i {DCMDIncludes} ∂
- -o AuditDCMD.c.o ∂
- AuditDCMD.c
- C ∂
- -i {DCMDIncludes} ∂
- -o AuditEntryFormat.c.o ∂
- AuditEntryFormat.c
- Link ∂
- -o Audit ∂
- {DCMDLibraries}dcmdGlue.a.o ∂
- AuditDCMD.c.o ∂
- AuditEntryFormat.c.o ∂
- "{Libraries}"Runtime.o ∂
- "{Libraries}"Interface.o
- {DCMD}BuildDcmd Audit 1000
- Echo 'include "Audit";' ∂
- | Rez -a -o "{systemFolder}Debugger Prefs"
- * - to here
- * Note: Be sure to link dcmdGlue.a.o first. The files in the
- * dcmd libraries folder are distributed with Macsbug.
- */
- #include <Types.h>
- /*
- * AuditDCMD.c
- * Copyright © 1992-93 Apple Computer Inc. All Rights Reserved.
- * Programmed by Martin Minow,
- * Internet: minow@apple.com
- * AppleLink: MINOW
- * Version of January 14, 1993
- *
- * Edit History
- * 93.01.09 MM First public release
- * 93.01.14 MM Think and MPW generate different record sizes;
- * a disaster if you create an Audit Record under
- * Think and call Audit compiled under MPW. Also
- * added a test for record sizes and included
- * record size information in the AuditRecord.
- *
- * This is a MacsBug DCMD that can display AuditRecord contents.
- */
- #include <Traps.h>
- #include <GestaltEqu.h>
- #include <Memory.h>
- #include "Audit.h"
- /*
- * This file should be copied from the MacsBug distribution. Note
- * that we have our own display routines: only dcmdDrawString,
- * dcmdDrawLine, and dcmdDrawText are used.
- */
- #include "dcmd.h"
- /*
- * The version id's are defined as (majorVersion << 8) | minorVersion
- */
- #define kAuditDCMDEarliestVersion ((1 << 8) | 1)
- #define kAuditDCMDLatestVersion ((1 << 8) | 1)
-
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
- /*
- * These values must match values in Audit.c
- */
- #define kAuditMagicHeaderSize 7 /* Size in longwords */
- #define kAuditMagicHeader_0 0x4E560000 /* First word in Gestalt result */
-
- #define LOG (*auditPtr)
- #define ENTRY (*entryPtr)
-
- AuditPtr DCMDGetAuditPtr(
- OSType gestaltSelector
- );
- void DumpAudit(
- register AuditPtr auditPtr
- );
- void DumpAuditEntry(
- register AuditPtr auditPtr,
- register AuditEntryPtr entryPtr
- );
- Boolean CompareString(
- const StringPtr a,
- const StringPtr b
- );
- void PutUnsignedLeadingZeros(
- unsigned long value,
- short digits
- );
- void PutHexLeadingZeros(
- unsigned long value,
- short digits
- );
- void PutUnsigned(
- unsigned long value
- );
- void PutSigned(
- signed long value
- );
- void PutOSType(
- OSType datum
- );
- void PutChar(
- unsigned char datum
- );
- void PutPascalString(
- const StringPtr datum
- );
- pascal void CommandEntry(
- dcmdBlock *paramPtr
- );
- pascal void dcmdSwapWorlds(void);
- void PutLine(void);
-
- pascal void
- CommandEntry(
- dcmdBlock *paramPtr
- )
- {
- register AuditPtr auditPtr;
- Str255 formatString;
- OSType gestaltSelector;
- Boolean oldEnableState;
-
- switch (paramPtr->request) {
- case dcmdDoIt:
- dcmdSwapWorlds(); /* TMON needs this */
- (void) dcmdGetNextParameter(formatString);
- while (formatString[0] < 4)
- formatString[++formatString[0]] = ' ';
- if (formatString[0] == (4 + 2)
- && formatString[1] == '\''
- && formatString[5] == '\'')
- BlockMove(&formatString[2], &gestaltSelector, 4);
- else {
- BlockMove(&formatString[1], &gestaltSelector, 4);
- }
- PutPascalString("\pAudit ");
- PutOSType(gestaltSelector);
- PutLine();
- auditPtr = DCMDGetAuditPtr(gestaltSelector);
- if (auditPtr == NULL) {
- dcmdDrawLine("\pUndefined audit area");
- goto drawHelp;
- }
- else {
- PutPascalString("\pAudit area at ");
- PutHexLeadingZeros((unsigned long) auditPtr, 8);
- PutLine();
- oldEnableState = (LOG.flags & kAuditEnabledMask) != 0;
- (void) dcmdGetNextParameter(formatString);
- if (CompareString("\pON", formatString)) {
- LOG.flags |= kAuditEnabledMask;
- PutPascalString("\pAuditing enabled, was ");
- goto turnOffExit;
- }
- else if (CompareString("\pOFF", formatString)) {
- LOG.flags &= ~kAuditEnabledMask;
- PutPascalString("\pAuditing disabled, was ");
- turnOffExit: PutPascalString((oldEnableState)
- ? "\penabled" : "\pdisabled");
- PutLine();
- }
- else if (CompareString("\pWRITE", formatString)
- || formatString[0] == 0)
- DumpAudit(auditPtr);
- else {
- dcmdDrawLine("\pUnknown Audit command.");
- goto drawHelp;
- }
- }
- dcmdSwapWorlds(); /* TMON needs this */
- break;
- case dcmdHelp:
- dcmdDrawLine("\pAudit formats Audit record area.");
- drawHelp: dcmdDrawLine("\pFormat: Audit NAME on | Audit NAME off"
- " | Audit NAME write");
- dcmdDrawLine("\pWhere NAME is the Audit Gestalt identifier.");
- dcmdDrawLine("\p\"Write\" is assumed if no command is given.");
- break;
- }
- }
-
- AuditPtr
- DCMDGetAuditPtr(
- OSType gestaltSelector
- )
- {
- auto long gestaltResponse;
- register AuditPtr auditPtr;
-
- auditPtr = NULL;
- if (Gestalt(gestaltSelector, &gestaltResponse) != noErr)
- dcmdDrawLine("\pNo such AuditRecord");
- else if (gestaltResponse == 0
- || (gestaltResponse & 0x3) != 0)
- dcmdDrawLine("\pThis is not an AuditRecord (wrong Gestalt value)");
- else {
- auditPtr = (AuditPtr) gestaltResponse;
- if (((unsigned long *) auditPtr)[-kAuditMagicHeaderSize]
- != kAuditMagicHeader_0) {
- dcmdDrawLine("\pThis is not an AuditRecord (wrong header)");
- auditPtr = NULL;
- }
- else if (LOG.version.u.low < kAuditDCMDEarliestVersion) {
- dcmdDrawLine("\pThis AuditRecord release is earlier than our minimum");
- auditPtr = NULL;
- }
- else if (LOG.version.u.high > kAuditDCMDLatestVersion) {
- dcmdDrawLine("\pThis AuditRecord release is later than our maximum");
- auditPtr = NULL;
- }
- else if (LOG.recordSize != kAuditRecordSize) {
- dcmdDrawLine("\pRecord size mismatch");
- PutPascalString("\pRecord size mismatch, expecting ");
- PutHexLeadingZeros(kAuditRecordSize, 8);
- PutPascalString(", got ");
- PutHexLeadingZeros(LOG.recordSize, 8);
- PutLine();
- auditPtr = NULL;
- }
-
-
- }
- return (auditPtr);
- }
-
- void
- DumpAudit(
- register AuditPtr auditPtr
- )
- {
- register AuditQueueEntryPtr queueEntryPtr;
-
- PutPascalString("\pAuditRecord version: ");
- PutHexLeadingZeros((unsigned long) LOG.version.u.low, 4);
- PutPascalString("\p low, ");
- PutHexLeadingZeros((unsigned long) LOG.version.u.high, 4);
- PutPascalString("\p high.");
- PutLine();
- PutPascalString("\pDebugging is ");
- PutPascalString(((LOG.flags & kAuditEnabledMask)
- ? "\penabled" : "\pdisabled"));
- if (LOG.lostData == 0)
- PutPascalString("\p, no lost data");
- else {
- PutUnsigned(LOG.lostData);
- PutPascalString("\p lost data");
- }
- PutPascalString("\p, User refNum: ");
- PutHexLeadingZeros((unsigned long) LOG.refNum, 8);
- PutLine();
- /*
- * First dump all entries in the free queue.
- */
- PutPascalString("\pAudit area (already displayed)");
- PutLine();
- queueEntryPtr = (AuditQueueEntryPtr) LOG.free.queue.qHead;
- if (queueEntryPtr != NULL) {
- for (;;) {
- DumpAuditEntry(auditPtr, &queueEntryPtr->theEntry);
- if (queueEntryPtr == (AuditQueueEntryPtr) LOG.free.queue.qTail)
- break;
- queueEntryPtr = (AuditQueueEntryPtr) queueEntryPtr->qLink;
- }
- }
- /*
- * Then dump all entries in the data queue.
- */
- PutPascalString("\pAudit area (to be displayed)");
- PutLine();
- queueEntryPtr = (AuditQueueEntryPtr) LOG.data.queue.qHead;
- if (queueEntryPtr != NULL) {
- for (;;) {
- DumpAuditEntry(auditPtr, &queueEntryPtr->theEntry);
- if (queueEntryPtr == (AuditQueueEntryPtr) LOG.data.queue.qTail)
- break;
- queueEntryPtr = (AuditQueueEntryPtr) queueEntryPtr->qLink;
- }
- }
- PutPascalString("\pEnd of Audit display");
- PutLine();
- }
-
- void
- DumpAuditEntry(
- register AuditPtr auditPtr,
- register AuditEntryPtr entryPtr
- )
- {
- Str255 result;
-
- #define DATA (ENTRY.data)
- if (ENTRY.tickCount != 0) {
- FormatAuditEntryTimestamp(auditPtr, entryPtr, result);
- PutPascalString(result);
- PutPascalString("\p: ");
- FormatAuditEntryData(entryPtr, result);
- PutPascalString(result);
- PutLine();
- }
- #undef DATA
- }
-
- /*
- * Compare two strings. a is the keyword we're looking
- * for: it is always specified in upper-case. b is
- * the test string. It is case-converted. Note that
- * this code presumes that the test words are in
- * 7-bit ASCII.
- */
- Boolean
- CompareString(
- const StringPtr a,
- const StringPtr b
- )
- {
- register short i;
- register unsigned char c;
-
- if (a[0] != b[0])
- return (FALSE);
- else {
- for (i = 1; i <= a[0]; i++) {
- c = b[i];
- if (c >= 'a' && c <= 'z')
- c -= ('a' - 'A');
- if (c != a[i])
- return (FALSE);
- }
- return (TRUE);
- }
- }
-
- /*
- * Output an n-digit value with leading zeros.
- */
- void
- PutUnsignedLeadingZeros(
- unsigned long value,
- short digits
- )
- {
- if (--digits > 0)
- PutUnsignedLeadingZeros(value / 10, digits);
- PutChar((value % 10) + '0');
- }
-
- /*
- * Output a signed decimal longword.
- */
- void
- PutSigned(
- signed long value
- )
- {
- if (value < 0) {
- PutChar('-');
- value = (-value);
- }
- PutUnsigned((unsigned long) value);
- }
-
- /*
- * Output an unsigned decimal longword.
- */
- void
- PutUnsigned(
- unsigned long value
- )
- {
- if (value >= 10)
- PutUnsigned(value / 10);
- PutChar((value % 10) + '0');
- }
-
- /*
- * Output a string of hex digits with leading zeros.
- */
- void
- PutHexLeadingZeros(
- unsigned long value,
- short digits
- )
- {
- if (--digits > 0)
- PutHexLeadingZeros(value >> 4, digits);
- value &= 0x0F;
- PutChar((value < 10)
- ? value + '0'
- : (value + ('A' - 10))
- );
- }
-
- /*
- * Output a 4-byte character string. Unknown
- * bytes (characters outside the range ' ' to '~')
- * are replaced as '.'.
- */
- void
- PutOSType(
- OSType datum
- )
- {
- char value[sizeof (OSType)];
- register short i;
- register unsigned char c;
-
- BlockMove(&datum, value, sizeof (OSType));
- PutChar('\'');
- for (i = 0; i < sizeof (OSType); i++) {
- c = value[i];
- if (c < ' ' || c >= 0x7F)
- c = '.';
- PutChar(c);
- }
- PutChar('\'');
- }
-
- void
- PutPascalString(
- const StringPtr datum
- )
- {
- dcmdDrawString(datum);
- }
-
-
- void
- PutChar(
- unsigned char datum
- )
- {
- char work[1];
-
- if (datum == '\n')
- PutLine();
- else {
- work[0] = datum;
- dcmdDrawText((StringPtr) work, sizeof (char));
- }
- }
-
- void
- PutLine(void)
- {
- dcmdDrawLine("\p");
- }
-